const puppeteer = require('puppeteer')
const fs = require('fs')

async function sleep(timeout = 3000) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(true)
    }, timeout)
  })
}

async function getConditions(page, condition, conditionIndex) {
  return new Promise(async (resolve, reject) => {
    try {
      await sleep(1500)
      await page.evaluate(() => {
        const ddl = document.querySelector('#stq_mobile_and_brand_dropdown > div:nth-child(3) > div')
        ddl.className += ' open'
      })
      const conditionBtn = await page.$(
        `#stq_mobile_and_brand_dropdown > div:nth-child(3) > div > ul > li:nth-child(${conditionIndex}) > a`
      )
      await conditionBtn.click()
      const stqgetPriceButton = await page.$('#stqgetPriceButton')
      await stqgetPriceButton.click()

      await sleep(1500)
      await page.evaluate(() => {
        window.scrollTo(0, 0)
      })
      await page.waitForSelector('#stq_back_btn_from_price')
      const basePrice = await page.evaluate(() => {
        const price = document.querySelector('#getPrice')
        return price ? price.innerText : 0
      })
      const backBtn = await page.$('#stq_back_btn_from_price')
      await backBtn.click()
      await sleep(1500)
      await page.waitForSelector('#stqgetPriceButton', { visible: true })
      console.log(condition, basePrice)
      return resolve(basePrice)
    } catch (error) {
      console.log(error.message)
      return reject(null)
    }
  })
}

async function getData(page, brand, bIndex, currentModelIndex) {
  return new Promise(async (resolve, reject) => {
    let data = []
    let mIndex = 0
    const conditions = ['Excellent', 'Good', 'Fair']
    try {
      await page.evaluate(() => {
        const brandDDL = document.querySelector('#stq_mobile_and_brand_dropdown > div:nth-child(2) > div.dropdown')
        brandDDL.className += ' open'
      })

      await sleep(1500)
      let $brand = await page.$(
        `#stq_mobile_and_brand_dropdown > div:nth-child(2) > div:nth-child(1) > ul > li:nth-child(${bIndex + 1}) > a`
      )
      await $brand.click()
      console.log('选中品牌', bIndex, brand)

      await sleep(1500)
      const models = await page.evaluate(() => {
        let result = []
        let mIndex = 0
        const elems = document.querySelectorAll('#selectModelMenu > li')
        elems.forEach(elem => {
          result.push(elem.innerText.trim())
        })
        return result
      })
      console.log('抓取所有Model', models.length)
      if (currentModelIndex >= models.length) {
        mIndex = 1
      } else {
        mIndex = currentModelIndex
      }
      for (; mIndex < models.length; mIndex++) {
        await sleep(1500)
        const model = models[mIndex]
        if ('Lumia 730 Dual SIM_Lumia 830_Galaxy S Duos 2 S7582'.indexOf(model) > -1) {
          continue
        }
        console.log('mIndex', mIndex, model)
        await page.evaluate(() => {
          const ddl = document.querySelector('#stq_mobile_and_brand_dropdown > div:nth-child(2) > div:nth-child(2)')
          ddl.className += ' open'
        })
        console.log('点击型号')
        let $model = await page.$(`#selectModelMenu > li:nth-child(${mIndex + 1}) > a`)
        await $model.click()
        for (let index = 0; index < conditions.length; index++) {
          let condition = conditions[index]
          const basePrice = await getConditions(page, condition, index + 1)
          data.push({
            brand: brand,
            model: model,
            condition,
            basePrice
          })
        }
      }
      resolve(data)
    } catch (error) {
      reject(error)
    }
  })
}

async function run(params) {
  console.time(1)

  // let data = []
  const fileSizeMax = 10
  let errorBrandName = ''
  let errorTimes = 0
  let currentModelIndex = 1

  const datastr = fs.readFileSync('./quikr_data.json')
  let data = JSON.parse(datastr) || []

  const browser = await puppeteer.launch({ headless: true })
  try {
    const page = await browser.newPage()
    await page.goto('https://www.quikr.com/QuikrX/guaranteed-purchase/sell-through-quikr')
    console.log('载入成功')
    const brandNames = await page.evaluate(() => {
      let brands = []
      const $brands = document.querySelectorAll(
        '#stq_mobile_and_brand_dropdown > div:nth-child(2) > div:nth-child(1) > ul > li'
      )
      $brands.forEach($brand => {
        brands.push($brand.innerText.trim())
      })
      return brands
    })

    for (let bIndex = 21; bIndex < brandNames.length; bIndex++) {
      const brand = brandNames[bIndex]
      try {
        let result = await getData(page, brand, bIndex, currentModelIndex)
        data = data.concat(data, result)
        errorTimes = 0
      } catch (error) {
        if (errorTimes >= 2 && errorBrandName === brand) {
          throw error
        } else {
          errorBrandName = brand
          errorTimes++
          console.log(bIndex, brand)
          bIndex--
          currentModelIndex = error
          continue
        }
        currentModelIndex = 1
      }
      if (bIndex % 10 === 0) {
        console.log(data.length)
        fs.writeFileSync(`quikr_data_${bIndex / 10}.json`, JSON.stringify(data))
        data = []
      }
    }

    await browser.close()
    console.timeEnd(1)
  } catch (error) {
    console.timeEnd(1)
    fs.writeFileSync('quikr_data.json', JSON.stringify(data))
    console.log(error)
    await browser.close()
  }
}

run()
